/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.kosongkosong.service.impl;

import com.kosongkosong.model.Match;
import com.kosongkosong.model.Phase;
import com.kosongkosong.model.Story;
import com.kosongkosong.model.id.StoryId;
import com.kosongkosong.service.DataService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jdo.support.JdoDaoSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author ifnu
 */
@Service("dataService")
@Transactional(readOnly=true)
public class DataServiceImpl extends JdoDaoSupport implements DataService{

    private static final Log LOGGER = LogFactory.getLog(DataService.class);

    @Autowired
    public DataServiceImpl(PersistenceManagerFactory factory) {
        setPersistenceManagerFactory(factory);
    }

    public Story getStory(String id) {
//        Collection<Story> stories =  getJdoTemplate().find(Story.class, "id==i","java.lang.String i",id);
        Query q = getPersistenceManager().newQuery(Story.class);
        q.setFilter("id==i");
        q.declareParameters("java.lang.String i");
        Collection<Story> stories = (Collection<Story>) q.execute(id);
        if(stories.isEmpty()){
            if(LOGGER.isDebugEnabled()){
                LOGGER.debug("story with id : " + id + " not found");
            }
            return null;
        } else {
            if(LOGGER.isDebugEnabled()){
                LOGGER.debug("story with id : " + id + " found");
            }
            return stories.iterator().next();
        }
    }

    public Story getHeadLine() {
        Query q = getPersistenceManager().newQuery(Story.class);
        q.setFilter("headline==i");
        q.declareParameters("java.lang.Boolean i");
        Collection<Story> stories = (Collection<Story>) q.executeWithArray(Boolean.TRUE);
        if(stories.isEmpty()){
            q = getPersistenceManager().newQuery(Story.class);
            q.setOrdering("id descending");
            stories = (Collection<Story>) q.execute();
        }
        if(!stories.isEmpty()){
            return stories.iterator().next();
        }
        return null;
    }

    @Transactional
    public void saveHeadline(Story story) {
        PersistenceManager manager = getPersistenceManager();
        Query q = manager.newQuery(Story.class);
        q.setFilter("headline==i");
        q.declareParameters("java.lang.Boolean i");
        Collection<Story> stories = (Collection<Story>) q.execute(Boolean.TRUE);
        if(stories.isEmpty()){
            if(LOGGER.isDebugEnabled()){
                LOGGER.debug("no stories with headline true found");
            }
        } else {
            for (Story s : stories) {
                s.setHeadline(Boolean.FALSE);
            }
        }

        manager.makePersistent(story);
    }

    @Transactional
    public void save(Story story) {
        getPersistenceManager().makePersistent(story);
    }

    @Transactional
    public void save(StoryId story){
        getPersistenceManager().makePersistent(story);
    }

    @Transactional
    public void update(Story story) {
        //copy all value to database to update
        Story s = getPersistenceManager().getObjectById(Story.class, story.getKey());
        s.setDateFetched(story.getDateFetched());
        s.setHeader(story.getHeader());
        s.setImageUrl(story.getImageUrl());
        s.setHeadline(Boolean.TRUE);
    }
    
    @Transactional
    public void save(Collection<Story> stories) {
        for (Story story : stories) {
            getPersistenceManager().makePersistent(story);
        }
    }

    public void save(Match match){
        getPersistenceManager().makePersistent(match);
    }

    public void update(Match match){
        Query q = getPersistenceManager().newQuery(Match.class);
        q.setFilter("id==i");
        q.declareParameters("java.lang.String i");
        Collection<Match> matches = (Collection<Match>) q.execute(match.getId());
        if(matches.isEmpty()){
            return;
        } else {
            Match m = matches.iterator().next();
            m.setTeamA(match.getTeamA());
            m.setTeamB(match.getTeamB());
        }
    }

    public void saveMatches(Collection<Match> mathes){
        for (Match match : mathes) {
            getPersistenceManager().makePersistent(match);
        }
    }

    public Match getMatch(String id) {
        Query q = getPersistenceManager().newQuery(Match.class);
        q.setFilter("id==i");
        q.declareParameters("java.lang.String i");
        Collection<Match> matches = (Collection<Match>) q.execute(id);
        if(matches.isEmpty()){
            return null;
        } else {
            return matches.iterator().next();
        }
    }

    public List<Match> getCompleteSchedule() {
        Query q = getPersistenceManager().newQuery(Match.class);
        q.setOrdering("id ascending");
        Collection<Match> matches = (Collection<Match>) q.execute();
        return new ArrayList<Match>(matches);
    }

    public List<Match> getSchedule(Phase phase) {
        Query q = getPersistenceManager().newQuery(Match.class);
        q.setFilter("stage==i");
        q.declareParameters("java.lang.String i");
        q.setOrdering("id ascending");
        Collection<Match> matches = (Collection<Match>) q.execute(phase.name());
        return new ArrayList<Match>(matches);
    }

    public List<Match> getGroupPhaseSchedule(String groupName) {
        Query q = getPersistenceManager().newQuery(Match.class);
        q.setFilter("group==i");
        q.declareParameters("java.lang.String i");
        Collection<Match> matches = (Collection<Match>) q.execute("Group " + groupName.trim().toUpperCase());
        return new ArrayList<Match>(matches);
    }

    @Transactional
    public void delete(Story story) {
        PersistenceManager manager = getPersistenceManager();
        story = manager.getObjectById(Story.class,story.getKey());
        manager.deletePersistent(story);
    }

    public List<Story> getStories(){
        PersistenceManager manager = getPersistenceManager();
        Query q = manager.newQuery(Story.class);
        Collection<Story> stories = (Collection<Story>) q.execute();
        manager.retrieveAll(stories);
        return new ArrayList<Story>(stories);
    }

    public StoryId getStoryId(String id){
        Query q = getPersistenceManager().newQuery(StoryId.class);
        q.setFilter("id==i");
        q.declareParameters("java.lang.String i");
        Collection<StoryId> stories = (Collection<StoryId>) q.execute(id);
        if(stories.isEmpty()){
            if(LOGGER.isDebugEnabled()){
                LOGGER.debug("story with id : " + id + " not found");
            }
            return null;
        } else {
            if(LOGGER.isDebugEnabled()){
                LOGGER.debug("story with id : " + id + " found");
            }
            return stories.iterator().next();
        }

    }

    public StoryId getHeadLineId() {
        Query q = getPersistenceManager().newQuery(StoryId.class);
        q.setFilter("headline==i");
        q.declareParameters("java.lang.Boolean i");
        Collection<StoryId> stories = (Collection<StoryId>) q.executeWithArray(Boolean.TRUE);
        if(stories.isEmpty()){
            q = getPersistenceManager().newQuery(StoryId.class);
            q.setOrdering("id descending");
            stories = (Collection<StoryId>) q.execute();
        }
        if(!stories.isEmpty()){
            return stories.iterator().next();
        }
        return null;
    }

    public List<Story> getStories(int start, int num) {
        Query q = getPersistenceManager().newQuery(Story.class);
        q.setOrdering("id descending");
        q.setRange(start, start+num);
        Collection<Story> stories = (Collection<Story>) q.execute();
        return new ArrayList<Story>(stories);
    }

    public List<StoryId> getStoryIds() {
        Query q = getPersistenceManager().newQuery(StoryId.class);
        q.setOrdering("id descending");
        Collection<StoryId> stories = (Collection<StoryId>) q.execute();
        return new ArrayList<StoryId>(stories);
    }

    public List<StoryId> getStoryIds(int start, int num) {
        Query q = getPersistenceManager().newQuery(StoryId.class);
        q.setOrdering("id descending");
        q.setRange(start, start+num);
        Collection<StoryId> stories = (Collection<StoryId>) q.execute();
        return new ArrayList<StoryId>(stories);
    }

}
